// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_logic_grid.h"
#include "mk_engine.h"
#include "mk_painter.h"
#include "mk_error.h"

namespace MK3DE
{
	CLogicGrid::CLogicGrid()
	{
		_grid = NULL;
		_width = 0;
		_height = 0;
		_gridSize = 0;
	}

	CLogicGrid::~CLogicGrid()
	{
		SAFE_DELETE_ARRAY(_grid);
	}

	BOOL CLogicGrid::Create(DWORD width, DWORD height, DWORD gridSize)
	{
		BOOL ret = FALSE;

		_grid = new BYTE[width * height];
		MK_PROCESS_ERROR(_grid);

		memset(_grid, 0, sizeof(BYTE) * width * height);
		_width = width;
		_height = height;
		_gridSize = gridSize;

		ret = TRUE;
Exit0:
		return ret;
	}

	void CLogicGrid::Render(DWORD centerX, DWORD centerY, DWORD halfSize)
	{
		DWORD startX = halfSize > centerX ? 0 : (centerX - halfSize);
		DWORD endX = (centerX + halfSize) > (_width - 1) ? (_width - 1) : centerX + halfSize;

		DWORD startY = halfSize > centerY ? 0 : (centerY - halfSize);
		DWORD endY = (centerY + halfSize) > (_height - 1) ? (_height - 1) : centerY + halfSize;

		CPainter* painter = GetEngine()->GetPainter();
		for (DWORD x = startX; x <= endX; ++x)
		{
			for (DWORD y = startY; y <= endY; ++y)
			{
				DWORD color = 0xffffffff;
				BYTE value = _grid[y * _width + x];
				stdext::hash_map<BYTE, DWORD>::iterator it = _mapGridColor.find(value);
				if (it != _mapGridColor.end())
					color = it->second;
				painter->DrawTriangle(D3DXVECTOR3(x * _gridSize + 2.0f, 0, y * _gridSize + 2.0f),
					D3DXVECTOR3((x + 1) * _gridSize - 2.0f, 0, y * _gridSize + 2.0f),
					D3DXVECTOR3(x * _gridSize + 2.0f, 0, (y + 1) * _gridSize - 2.0f),
					D3DXVECTOR2(0, 0), D3DXVECTOR2(0, 0), D3DXVECTOR2(0, 0), color, color, color, NULL);

				painter->DrawTriangle(D3DXVECTOR3((x + 1) * _gridSize - 2.0f, 0, y * _gridSize + 2.0f),
					D3DXVECTOR3(x * _gridSize + 2.0f, 0, (y + 1) * _gridSize - 2.0f),
					D3DXVECTOR3((x + 1) * _gridSize - 2.0f, 0, (y + 1) * _gridSize - 2.0f),
					D3DXVECTOR2(0, 0), D3DXVECTOR2(0, 0), D3DXVECTOR2(0, 0), color, color, color, NULL);
			}
		}
	}

	void CLogicGrid::Paint(DWORD centerX, DWORD centerY, DWORD halfSize, BYTE value)
	{
		DWORD startX = halfSize > centerX ? 0 : (centerX - halfSize);
		DWORD endX = (centerX + halfSize) > (_width - 1) ? (_width - 1) : centerX + halfSize;

		DWORD startY = halfSize > centerY ? 0 : (centerY - halfSize);
		DWORD endY = (centerY + halfSize) > (_height - 1) ? (_height - 1) : centerY + halfSize;

		for (DWORD x = startX; x <= endX; ++x)
			for (DWORD y = startY; y <= endY; ++y)
				_grid[y * _width + x] = value;
	}

	void CLogicGrid::SetGridColor(BYTE value, DWORD color)
	{
		_mapGridColor[value] = color;
	}

	BOOL CLogicGrid::SaveToFile(const char* fileName)
	{
		FILE* fp = fopen(fileName, "wb");
		if (fp == NULL)
			return FALSE;

		fwrite(&_width, sizeof(_width), 1, fp);
		fwrite(&_height, sizeof(_height), 1, fp);
		fwrite(&_gridSize, sizeof(_gridSize), 1, fp);
		fwrite(_grid, sizeof(BYTE), _width * _height, fp);
		fclose(fp);
		return TRUE;
	}
}
